package com.example.mcu.serial;



import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidParameterException;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

import com.example.mcu_up.serial.BadPackageException;
import com.example.mcu_up.serial.NoInput;



import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android_serialport_api.SerialPort;



public class Serial  {

	protected static SerialPort mSerialPort;
	protected OutputStream mOutputStream;
	private InputStream mInputStream;
	Handler handler;
	ReceiveThread mReceiveThread=new ReceiveThread();
	SendingThread mSendingThread= new SendingThread();
	HandleThread handleThread= new HandleThread();

	boolean isrunning = false;
    Queue<Pack> sendqueue = new ConcurrentLinkedQueue<Pack>();
    Queue<Pack> readqueue = new ConcurrentLinkedQueue<Pack>();
   
    public static Serial serial;
    public Serial(){
	try {
		    mSerialPort =new SerialPort(new File("/dev/ttyS2"),115200, 0);
			mOutputStream = mSerialPort.getOutputStream();
			mInputStream = mSerialPort.getInputStream();
		} catch (InvalidParameterException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		} 
	}

    /*
     * 这个方法是设置端口的
     * 
     */
    public void setSerialPort(String dev,int port){
    	try {
			mSerialPort =new SerialPort(new File(dev), port, 0);
		} catch (SecurityException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
    }
    
   
	public static Serial getInstance(){
		if(serial==null){
			serial=new Serial();
		}
		return serial;
	}
    
	public void setHandler(Handler handler){
		this.handler=handler;
	}
	
	/**
	 * 开启串口相关的工作线程
	 */
	public void start() {

		isrunning = true;
		if (mSerialPort != null) {

			if (!mSendingThread.isAlive()) {
				mSendingThread.start();
			}
			if (!mReceiveThread.isAlive()) {
				mReceiveThread.start();
			}
			if (!handleThread.isAlive()) {
				handleThread.start();
			}
		}
	}
	/**
	 * 关闭串口相关的工作线程
	 */
	public void stop() {

		isrunning = false;
		if (mSendingThread != null) {
			try {
				mSendingThread.join(500);
				mSendingThread.interrupt();
				mSendingThread = null;
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		if (mReceiveThread != null) {
			try {
				mReceiveThread.join(500);
				mReceiveThread.interrupt();
				mReceiveThread = null;
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		if (handleThread != null) {
			try {
				handleThread.join(500);
				handleThread.interrupt();
				handleThread = null;
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	private class ReceiveThread extends Thread {
		  Pack p=null;
		@Override
		public void run() {
			super.run();
			Log.d("mytestpack", "receive thread is running");
			while(isrunning) {
				try {
					if (mInputStream == null) {
						throw new NoInput("串口未初始化！");
				    }
					 p=new Pack();
				    	p=p.getPack(mInputStream);
					readqueue.add(p);
					Log.d("mytestpack","received type:"+p.getType());
				} catch (IOException e) {
					e.printStackTrace();
					return;
				} catch (NoInput e) {
					// TODO 自动生成的 catch 块
					e.printStackTrace();
				} catch (BadPackageException e) {
					
					e.printStackTrace();
				}
			}
		}
	}

	static int i=0;
	//int是十六进制的数
	public void send(Pack p){
		
		
		
    	if(p.getType()==(byte)0x00){
			sendqueue.add(p);
		}else{
			sendqueue.add(p);
		
			
		
			
		}	
	}

	
	
	
   public	class SendingThread extends Thread {
		@Override
		
		
		public void run() {
	   
			while (isrunning) {
				try {
					
					Pack p = sendqueue.poll();
					if(p == null){
						try {
							Thread.sleep(50);
							continue;
						} catch (InterruptedException e) {

						}
					}
					if (mOutputStream != null) {
						mOutputStream.write(p.tobytes());
						
					} else {
						return;
					}
				} catch (IOException e) {
					e.printStackTrace();
					return;
				}
			}}
		
	}
		
		
   public	class HandleThread extends Thread {
		
	public void run() {
		// TODO 自动生成的方法存根
		super.run();
		while (isrunning) {
			Pack p= readqueue.poll();
			if(p == null){
				try {
					Thread.sleep(500);
					continue;
				} catch (InterruptedException e) {
				}
			}else
			{
				
					Message message=new Message();
					message.what=1;
					message.obj=p;
					handler.sendMessage(message);
					
					
					
			}	    }
	}
   }

    public void closeSerialPort() {
	if (mSerialPort != null) {
		mSerialPort.close();
		stop();
		mSerialPort = null;
	}
    
    }
}
